6 características importantes de strict mode en JS

El strict mode es un set de reglas que habilita un modo de operación más recomendable para Javascript.

Este modo se introdujo en ES5, y us propósito era precisamente habilitar reglas que ayudaran a escribir código con buenas prácticas de progamación. Aunque su uso se mantuvo opcional para no interferir con el estándar en ese momento.

Para identificar si un archivo de JS lo esta utilizando debes buscar la directiva:

'use strict'

Claro, conforme han salido nuevas versiones de Javascript, muchas de las nuevas funcionalidades traen implícitamente el comportamiento de strict mode. Un ejemplo son los módulos y las clases introducidos en ES6.

No obstante siempre es recomendable asegurarse de estar utlizandolo ya que hay cosas que pueden pasar en otras áreas de Javascript. Cosas que a otros lenguajes les parecería una aberración.

1.Previene la creación accidental de variables globales

Este es en mi opinión el peor de los pecados de JS. Si asignas un valor a una variable no declarada, Javascript te hace el favor de crearla, en lugar de avisarte que no lo hiciste.

newValue = 23
console.log(newValue) // 23

Esto va en contra de las buenas prácticas porque da pie a que se encuentren variables ocultas a lo largo del código y sea más dificíl debuggear cuando eso suceda.

Strict mode viene a poner las cosas en orden. Como debe ser.

'use strict'

newValue = 23
console.log(newValue) // ReferenceError: newValue is not defined

2.Evita equivocaciones al intentar borrar propiedades

Javascript por default permite borrar las propiedades de un objeto con la keyword delete:

let obj = {
    value: 50
}
console.log(obj.value) // 50
delete obj.value
console.log(obj.value) // undefined

Sin embargo no permite borrar variables ni objetos directamente:

let obj = {
    value: 50
}
console.log(obj) // { value: 50 }
delete obj
console.log(obj) // { value: 50 }

Cómo puedes cuando intentar borrar un objeto simplemente lo ignora en vez de decirte algo al respecto. Por eso mismo strict mode habililta un mensaje de error apropiado:

'use strict'

let obj = {
    value: 50
}
console.log(obj) // SyntaxError: Delete of an unqualified identifier in strict mode.
delete obj
console.log(obj)

3.Previene la utilización de nombres duplicados en los parámetros de una misma función

Increiblemente Javascript permite que se repitan nombres en los parámetros que definas para una función.

function addition(valueA, valueA) {
    return valueA + valueA
}
console.log(addition(1,4)) // 8

*Si. El resultado es incorrecto. Precisamente por eso no debería permitirse este comportamiento en primer lugar.

Con strict mode verás el comportamiento que normalmente esperarías tras haber escrito algo así:

'use strict'

function addition(valueA, valueA) {
    return valueA + valueA
}
console.log(addition(1,4)) // SyntaxError: Duplicate parameter name not allowed in this context

4.Impide asignar valores a una propiedad de solo lectura

En JS se puede especificar que una variable sea de solo lectura. Esto ayuda a prevenir que el valor de una variable cambie.

let userObject = {}

Object.defineProperty(userObject, 'username', {value: 'ProfHu1k', writable: false})
console.log(userObject.username) // ProfHu1k

userObject.username = 'BruceBan'
console.log(userObject.username) // ProfHu1k

Como puedes ver el código pareceria haber ignorado la asignación del valor nuevo BruceBan a la propiedad username. Esto es comportamiento esperado, pero siendo sinceros sería mejor que se lanzará un error antes de compilar el código.

Si te pones a pensarlo, si se hizo una variable de solo lectura y aun así se le esta reasignando un valor es más que obvio que no fue intencional.

'use strict'

let userObject = {}

Object.defineProperty(userObject, 'username', {value: 'ProfHu1k', writable: false})
console.log(userObject.username) // ProfHu1k

userObject.username = 'BruceBan' // throws Error: TypeError: Cannot assign to read only property 'username' of object '#<Object>'
console.log(userObject.username)

5.Impide utilizar la keyword eval como nombre en una variable

En Javascript eval permite ejecutar código a partir de un string. Es una funcionalidad poco recomendable de utilizar, ya que abre el camino a inyectar código malicioso por medio de texto en tus scripts. Sin embargo existe y al exisitir pero porsupuesto que se ha usado.

eval('console.log("Log from eval")') // Log from eval

let eval = () => {
    console.log('custom function')   
}
console.log(eval()) // ReferenceError: Cannot access 'eval' before initialization

A diferencia de casos anteriores, en este si se lanza un error. Pero no es un error adecuado. El mensaje indica que no se iinicializó la variable cuando la realidad es que se acaba de hacer eso en la línea anterior…

'use strict'

eval('console.log("Log from eval")') // Log from eval

let eval = () => { // SyntaxError: Unexpected eval or arguments in strict mode
    console.log('custom function')   
}
console.log(eval)

Ahora si. Con use strict este error si tiene sentido y protege la keyword eval como debe de ser.

6.Impide utilizar la keyword arguments como nombre en una variable

Otro keyword importante en JS es arguments. Sin embargo, a diferencia de evals, su uso es más común, ya que sirve para acceder a los parámetros de una función.

function startPlaylist(playlistId, loop) {
    console.log(arguments[0]) // 10
    console.log(arguments[1]) // false
}

startPlaylist(10, false)

Pero como ya te imaginarás Javascript permite sobreescribir la variable, causando comportamiento inesperado:

function startPlaylist(playlistId, loop) {
    console.log(arguments[0]) // ReferenceError: Cannot access 'arguments' before initialization
    console.log(arguments[1])

    let arguments = 34
    console.log(arguments)
}

startPlaylist(10, false)

Al intentar ejecutar este código, la consola nos regresa un error sin sentido. Pero con strict mode eso se compone.

'use strict'

function startPlaylist(playlistId, loop) {
    console.log(arguments[0])
    console.log(arguments[1])

    let arguments = 34 // SyntaxError: Unexpected eval or arguments in strict mode
    console.log(arguments)
}

startPlaylist(10, false)

Estos son los mas importantes aunque también hay otros como:

  • Prohibir el uso de literales de octales sin el prefijo: o
  • Prohibir las secuencias de escape: \
  • Prohibir el uso de with

Por definición utilizar use strict debería ser prácticamente obligatorio. Y de hecho como mencionaba al principio, prácticamente lo es, al menos para las nuevas funcionalidades que se han ido agregando .

No te dejes engañar. Si no ves use strict en código de Javascript no significa que no se este usando. Sin embargo es importante que sepas de su existencia porque todavía puedes toparte con código antiguo que no hacía uso del mismo.